:- use_module(library(clpfd)).


zip([],[],[]).

zip([F1|L1], [F2|L2], [Pair|R]) :-
	Pair= -(F1,F2),
	zip(L1,L2,R).
	
value(K-V, V).

writeList([]) :- nl.

writeList([First|Rest]) :-
	write(First),
	nl,
	writeList(Rest).


reorder(Positions, Values, Reordered) :-
	zip(Positions, Values, Zipped),
	keysort(Zipped, Sorted),
	maplist(value, Sorted, Reordered).


einstein([FarbenX, NationenX, TiereX, ZigarettenX, DrinksX]) :-
	[Rot, Weiss, Gruen, Gelb, Blau] = Farben,
	[Brite, Schwede, Daene, Norweger, Deutsche] = Nationen,
	[Hund, Vogel, Katze, Pferd, Fish] = Tiere,
	[Pallmall, Dunhill, Malboro, Winfield, Rothmanns] = Zigaretten,
	[Tee, Kaffee, Milch, Bier, Wasser] = Drinks,
	
	Farben ins 1..5,
	Nationen ins 1..5,
	Tiere ins 1..5,
	Zigaretten ins 1..5,
	Drinks ins 1..5,
	
	all_different(Farben),
	all_different(Nationen),
	all_different(Tiere),
	all_different(Zigaretten),
	all_different(Drinks),
	
	Brite #= Rot, 				%1
	Schwede #= Hund,  			%2
	Daene #= Tee,	  			%3
	Gruen #= Weiss - 1, 		%4
	Gruen #= Kaffee,   			%5
	Pallmall #= Vogel,			%6
	Milch #= 3,					%7
	Gelb #= Dunhill,			%8
	Norweger #= 1,				%9
	abs(Malboro - Katze) #= 1,	%10
	abs(Pferd - Dunhill) #= 1,	%11
	Winfield #= Bier,			%12
	abs(Norweger - Blau) #= 1,	%13
	Deutsche #= Rothmanns,		%14
	abs(Malboro - Wasser) #= 1, %15
  
  	%Variablen belegen
  	label(Farben),
  	label(Nationen),
  	label(Tiere),
  	label(Zigaretten),
  	label(Drinks),
  	 
  	reorder(Farben, [rot, weiss, gruen, gelb, blau], FarbenX),
  	reorder(Nationen, [brite, schwede, daene, norweger, deutsche], NationenX),
  	reorder(Tiere, [hund, vogel, katze, pferd, fish], TiereX),
  	reorder(Zigaretten, [pallmall, dunhill, malboro, winfield, rothmanns], ZigarettenX),
  	reorder(Drinks, [tee, kaffee, milch, bier, wasser], DrinksX).
  	